/**
 * 通用js方法封装处理
 * Copyright (c) 2023 dfec
 */

/**
 * 日期格式化
 * @param {any} time        时间戳
 * @param {String} pattern  要转换的格式(可不传，默认为{y}-{m}-{d} {h}:{i}:{s})
 * @returns String
 * @directions const thisTime = parseTime(new Date(), '{y}-{m}-{d}');
 * 2022-09-08
 */
const parseTime = (time, pattern) => {
    if (!time) {
        return null
    }
    const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
    let date
    if (typeof time === 'object') {
        date = time
    } else {
        if (typeof time === 'string' && /^[0-9]+$/.test(time)) {
            time = parseInt(time)
        } else if (typeof time === 'string') {
            time = time
                .replace(new RegExp(/-/gm), '/')
                .replace('T', ' ')
                .replace(new RegExp(/\.[\d]{3}/gm), '')
        }
        if (typeof time === 'number' && time.toString().length === 10) {
            time = time * 1000
        }
        date = new Date(time)
    }
    const formatObj = {
        y: date.getFullYear(),
        m: date.getMonth() + 1,
        d: date.getDate(),
        h: date.getHours(),
        i: date.getMinutes(),
        s: date.getSeconds(),
        a: date.getDay()
    }
    const timeStr = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
        let value = formatObj[key]
        // Note: getDay() returns 0 on Sunday
        if (key === 'a') {
            return ['日', '一', '二', '三', '四', '五', '六'][value]
        }
        if (result.length > 0 && value < 10) {
            value = '0' + value
        }
        return value || 0
    })
    return timeStr
}

/**
 * 表单重置
 * @param {String} refName  要重置的表单ref属性
 * @directions resetForm('submitForm')
 */
const resetForm = refName => {
    if (this.$refs[refName]) {
        this.$refs[refName].resetFields()
    }
}

/**
 * 处理表单中的日期范围参数
 * @param {Object} params    表单参数
 * @param {Array} dateRange  日期范围
 * @param {String} propName  字段名称
 * @returns Object
 * @directions const newParams = this.utils.addDateRange({name: 'xx', age: 'xxx'}, ['2022-01-01', '2021-01-02'], 'use');
 * {
 *      name: 'xx',
 *      age: 'xxx',
 *      params:{
 *          beginuse:'2022-01-01',
 *          enduse:'2021-01-02'
 *      }
 * }
 */
const addDateRange = (params, dateRange, propName) => {
    let search = params
    search.entity.params =
        typeof search.entity.params === 'object' &&
        search.entity.params !== null &&
        !Array.isArray(search.entity.params)
            ? search.entity.params
            : {}
    dateRange = Array.isArray(dateRange) ? dateRange : []
    if (typeof propName === 'undefined') {
        search.entity.params['beginTime'] = dateRange[0]
        search.entity.params['endTime'] = dateRange[1]
    } else {
        search.entity.params['begin' + propName] = dateRange[0]
        search.entity.params['end' + propName] = dateRange[1]
    }
    return search
}

/**
 * 数据词典key-value转化
 * @param {Object} datas
 * @param {Array} value
 * @returns string
 * @directions
 *
 */
const selectDictLabel = (datas, value) => {
    if (value === undefined) {
        return ''
    }
    var actions = []
    Object.keys(datas).some(key => {
        if (datas[key].value === '' + value) {
            actions.push(datas[key].label)
            return true
        }
    })
    if (actions.length === 0) {
        actions.push(value)
    }
    return actions.join('')
}

/**
 * 回显数据词典
 * @param {Object} datas
 * @param {*} value
 * @param {*} separator
 * @returns
 */
const selectDictLabels = (datas, value, separator) => {
    if (value === undefined) {
        return ''
    }
    var actions = []
    var currentSeparator = undefined === separator ? ',' : separator
    var temp = value.split(currentSeparator)
    Object.keys(value.split(currentSeparator)).some(val => {
        var match = false
        Object.keys(datas).some(key => {
            if (datas[key].value === '' + temp[val]) {
                actions.push(datas[key].label + currentSeparator)
                match = true
            }
        })
        if (!match) {
            actions.push(temp[val] + currentSeparator)
        }
    })
    return actions.join('').substring(0, actions.join('').length - 1)
}

/**
 * 字符串格式化(%s )
 * @param {String} str
 * @returns
 */
const sprintf = str => {
    let args
    var flag = true
    var i = 1
    str = str.replace(/%s/g, function() {
        var arg = args[i++]
        if (typeof arg === 'undefined') {
            flag = false
            return ''
        }
        return arg
    })
    return flag ? str : ''
}

/**
 * 转换字符串，undefined,null等转化为""
 * @param {undefined | null} str
 * @returns
 */
const parseStrEmpty = str => {
    if (!str || str === 'undefined' || str === 'null') {
        return ''
    }
    return str
}

/**
 * 对象合并
 * @param {Object} source
 * @param {Object} target
 * @returns
 */
const mergeRecursive = (source, target) => {
    for (var p in target) {
        try {
            if (target[p].constructor === Object) {
                source[p] = mergeRecursive(source[p], target[p])
            } else {
                source[p] = target[p]
            }
        } catch (e) {
            source[p] = target[p]
        }
    }
    return source
}

/**
 * 构造树型结构数据
 * @param {*} data 数据源
 * @param {*} id id字段 默认 'id'
 * @param {*} parentId 父节点字段 默认 'parentId'
 * @param {*} children 孩子节点字段 默认 'children'
 */
const handleTree = (data, id, parentId, children) => {
    let config = {
        id: id || 'id',
        parentId: parentId || 'parentId',
        childrenList: children || 'children'
    }
    var childrenListMap = {}
    var nodeIds = {}
    var tree = []

    for (let d of data) {
        let parentId = d[config.parentId]
        if (
            childrenListMap[parentId] === null ||
            childrenListMap[parentId] === undefined
        ) {
            childrenListMap[parentId] = []
        }
        nodeIds[d[config.id]] = d

        childrenListMap[parentId].push(d)
    }

    for (let d of data) {
        let parentId = d[config.parentId]
        if (nodeIds[parentId] === null || nodeIds[parentId] === undefined) {
            tree.push(d)
        }
    }

    for (let t of tree) {
        adaptToChildrenList(t)
    }

    function adaptToChildrenList(o) {
        if (childrenListMap[o[config.id]] !== null) {
            o[config.childrenList] = childrenListMap[o[config.id]]
        }
        if (o[config.childrenList]) {
            for (let c of o[config.childrenList]) {
                adaptToChildrenList(c)
            }
        }
    }
    return tree
}

/**
 * 参数处理
 * @param {*} params  参数
 */
const tansParams = params => {
    let result = ''
    for (const propName of Object.keys(params)) {
        const value = params[propName]
        var part = encodeURIComponent(propName) + '='
        if (value !== null && value !== '' && typeof value !== 'undefined') {
            if (typeof value === 'object') {
                for (const key of Object.keys(value)) {
                    if (
                        value[key] !== null &&
                        value[key] !== '' &&
                        typeof value[key] !== 'undefined'
                    ) {
                        let params = propName + '[' + key + ']'
                        var subPart = encodeURIComponent(params) + '='
                        result += subPart + encodeURIComponent(value[key]) + '&'
                    }
                }
            } else {
                result += part + encodeURIComponent(value) + '&'
            }
        }
    }
    return result
}

/**
 * 验证是否为blob格式
 * @param {Object} data
 * @returns
 */
const blobValidate = async data => {
    try {
        const text = await data.text()
        JSON.parse(text)
        return false
    } catch (error) {
        return true
    }
}

/**
 * 获得 Vue 应用的访问路径
 *
 * @param path 路径
 */
const getPath = path => {
    // 基础路径，必须以 / 结尾
    let basePath = getBasePath()
    if (!basePath.endsWith('/')) {
        return basePath + '/'
    }
    // 访问路径，必须不能以 / 开头
    if (path.startsWith('/')) {
        path = path.substring(1)
    }
    return basePath + path
}

/**
 * 获得 Vue 应用的基础路径
 */
const getBasePath = () => {
    return process.env.VUE_APP_BASE_PATH || '/'
}

/**
 * 转驼峰
 * @param {String} str
 * @param {Boolean} upperCaseFirst
 * @returns
 */
const toCamelCase = (str, upperCaseFirst) => {
    str = (str || '').toLowerCase().replace(/-(.)/g, function(match, group1) {
        return group1.toUpperCase()
    })
    if (upperCaseFirst && str) {
        str = str.charAt(0).toUpperCase() + str.slice(1)
    }
    return str
}
/**
 * 用于表格列筛选的穿梭框数据处理
 * @param {Array} dataList
 * @param {String} label
 * @param {Array} disabled
 * @returns
 */
const assemblyDataByTableColumn = (dataList, label, disabled) => {
    let newArray = []
    ;(dataList.length > 0) &
        dataList.forEach(element => {
            const obj = {
                key: element[label],
                label: element[label],
                disabled: false
            }
            newArray.push(obj)
        })
    if (newArray.length > 0 && disabled.length > 0) {
        newArray.forEach(element => {
            disabled.forEach(ele => {
                if (element.label === ele) {
                    element.disabled = true
                }
            })
        })
    }
    return newArray
}

/**
 * 用于表格列筛选的穿梭框数据反向转换
 * @param {*} dataList
 * @param {*} checkedList
 * @returns
 */
const assemblyDataByTableColumnResive = (dataList, checkedList) => {
    if (dataList.length > 0 && checkedList.length > 0) {
        return dataList.filter(item => checkedList.indexOf(item.label) == -1)
    }
}

/**
 * 修改配置表单项的值
 * @param {Array} items 所有配置项列表
 * @param {String} prop 配置项的唯一key值
 */
const setFormItemProp = (itemList, prop, key, value) => {
    if (Array.isArray(itemList) && itemList.length) {
        for (let i = 0; i < itemList.length; i++) {
            const element = itemList[i]
            element.forEach(v => {
                if (v.prop === prop) {
                    v[key] = value
                }
            })
        }
        return itemList
    } else {
        return
    }
}
/**
 * 修改下拉的显示值
 * @param {*} itemList
 * @param {*} label
 * @param {*} value
 * @returns
 */
const setSelectFormart = (itemList, label, value) => {
    if (Array.isArray(itemList) && itemList.length) {
        for (let i = 0; i < itemList.length; i++) {
            const element = itemList[i]
            element.label = element[label]
            element.value = element[value]
        }
        return itemList
    } else {
        return []
    }
}
/**
 * 获取uuid
 * @returns
 */
const getUuid = params => {
    let length = Number(params)
    var s = []
    var hexDigits = '0123456789abcdef'
    for (var i = 0; i < (length ? length : 32); i++) {
        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1)
    }
    s[14] = '4'
    s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1)
    s[8] = s[13] = s[18] = s[23]
    var uuid = s.join('')
    console.log('uuid', uuid)
    return uuid
}
export {
    parseTime,
    resetForm,
    addDateRange,
    selectDictLabel,
    selectDictLabels,
    sprintf,
    parseStrEmpty,
    mergeRecursive,
    handleTree,
    tansParams,
    blobValidate,
    getPath,
    getBasePath,
    toCamelCase,
    assemblyDataByTableColumn,
    assemblyDataByTableColumnResive,
    setFormItemProp,
    setSelectFormart,
    getUuid
}
